I manually picked 12 representatives from each category:

chicken_0116 chicken_0131 (so hard to distinguish) chicken_0181 chicken_0218 chicken_0264 chicken_0306 chicken_0383 chicken_0761 chicken_0646 chicken_0599 (only a leg) chicken_0891 (dark color) chicken_0999

dog_0010 dog_0021 (typical hair) dog_0023 dog_0033 dog_0095 dog_0146 (only a leg) dog_0147 dog_0342 (smooth surface) dog_0404 dog_0432 dog_0608 dog_0887

Some outliers in the whole dataset exist and may result in prediction errors.

Some ideas: - Extract surface texture which stands out with curvy grains (? hard to realize) - Color RGB feature (success) - Color HSV feature

Here I pick 5 images (3 fried chickens and 2 dogs) to do a image exloration demo.

Change to Greyscale, blue and red channels

file.bw=list()
file.bl=list()
file.red=list()
for (i in 1:5){
  file.bw[[i]]=channel(filename[[i]],mode="grey")
  display(file.bw[[i]])
}

for (i in 1:5) {
  file.bl[[i]]=channel(filename[[i]], mode='asblue')
  display(channel(filename[[i]], mode='asblue'))
}

for (i in 1:5) {
  file.red[[i]]=channel(filename[[i]], mode='asred')
  display(channel(filename[[i]], mode='asred'))
}

Extract the texture by high contrast on blue channel, which really shows difference to me between fried chicken and dogs.

file.contrast=list()
for (i in 1:5){
  file.contrast=file.bl[[i]]*5
  display(file.bl[[i]]*5)
}

Filtering: high pass

filter_high <- matrix(1, nc = 3, nr = 3)
filter_high[2, 2] <- -8
file.hi=list()
for (i in 1:5){
  file.hi <- filter2(filename[[i]], filter_high)
  display(file.hi)# high pass
}

Adaptive thresholding

for (i in 1:5){
  file.bw[[i]]=channel(filename[[i]],mode="grey")
  img_seg1 <- thresh(file.bw[[i]], w=60, h=60, offset=0.06)
  display(img_seg1, all=TRUE)
}

Outline Analysis

#Oriented Contour ### didn't see any use
img_leaf=list()
img_leaf1=list()
oc=list()
for (i in 1:5){
  img_leaf[[i]] <- resize(filename[[i]], 128, 128)
  img_leaf[[i]] <- channel(img_leaf[[i]], mode="gray")
  img_leaf1[[i]] <- thresh(img_leaf[[i]], w=50, h=50, offset=0.05)
  display(img_leaf1[[i]])}

for (i in 1:5){
  oc[[i]] <- ocontour(bwlabel(img_leaf1[[i]]))
  plot(oc[[i]][[1]], type='l');points(oc[[i]][[1]], col=2)
}

#Local Curvature
lc=list()
i=list()
neg=list()
pos=list()
for (k in 1:5){
  lc[[k]] <- localCurvature(x=oc[[k]][[1]], h=11)
  i[[k]] <- lc[[k]]$curvature >= 0
  neg[[k]] <- array(0, dim(img_leaf1[[k]]))
  pos[[k]] <- neg[[k]]
  pos[[k]][lc[[k]]$contour[i[[k]],]+1]  <- lc[[k]]$curvature[i[[k]]]
  neg[[k]][lc[[k]]$contour[!i[[k]],]+1] <- -lc[[k]]$curvature[!i[[k]]]
  display(10*(rgbImage(pos[[k]], , neg[[k]])), title = "Image curvature")
}

Color Features from RGB

By discretizing the RGB values, we can get a set of color features. We subdivide the pixel values in each color channel into multiple bands of equal width. Then the counts of pixels in correponding bins consist of a set of color features that characterizes the color distribution of the image.

str(rgb_feature)
List of 5
 $ : num [1:800] 0.01379 0.02122 0.02635 0.02134 0.00368 ...
 $ : num [1:800] 0.00301 0.01485 0.01819 0.02569 0.02503 ...
 $ : num [1:800] 7.88e-06 1.38e-03 8.54e-03 9.58e-03 3.15e-04 ...
 $ : num [1:800] 0.001236 0.005528 0.006125 0.000306 0 ...
 $ : num [1:800] 0.01459 0.01061 0.01105 0.00498 0.00152 ...
LS0tCnRpdGxlOiAiSW1hZ2UgRmVhdHVyZSBFeHBsb3JhdGlvbiIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyBJIG1hbnVhbGx5IHBpY2tlZCAxMiByZXByZXNlbnRhdGl2ZXMgZnJvbSBlYWNoIGNhdGVnb3J5OgoKY2hpY2tlbl8wMTE2CmNoaWNrZW5fMDEzMSAoc28gaGFyZCB0byBkaXN0aW5ndWlzaCkKY2hpY2tlbl8wMTgxCmNoaWNrZW5fMDIxOApjaGlja2VuXzAyNjQKY2hpY2tlbl8wMzA2CmNoaWNrZW5fMDM4MwpjaGlja2VuXzA3NjEKY2hpY2tlbl8wNjQ2CmNoaWNrZW5fMDU5OSAob25seSBhIGxlZykKY2hpY2tlbl8wODkxIChkYXJrIGNvbG9yKQpjaGlja2VuXzA5OTkKCmRvZ18wMDEwCmRvZ18wMDIxICh0eXBpY2FsIGhhaXIpCmRvZ18wMDIzCmRvZ18wMDMzCmRvZ18wMDk1CmRvZ18wMTQ2IChvbmx5IGEgbGVnKQpkb2dfMDE0Nwpkb2dfMDM0MiAoc21vb3RoIHN1cmZhY2UpCmRvZ18wNDA0CmRvZ18wNDMyCmRvZ18wNjA4CmRvZ18wODg3CgoKU29tZSBvdXRsaWVycyBpbiB0aGUgd2hvbGUgZGF0YXNldCBleGlzdCBhbmQgbWF5IHJlc3VsdCBpbiBwcmVkaWN0aW9uIGVycm9ycy4KCgpTb21lIGlkZWFzOgotIEV4dHJhY3Qgc3VyZmFjZSB0ZXh0dXJlIHdoaWNoIHN0YW5kcyBvdXQgd2l0aCBjdXJ2eSBncmFpbnMgKD8gaGFyZCB0byByZWFsaXplKQotIENvbG9yIFJHQiBmZWF0dXJlIChzdWNjZXNzKQotIENvbG9yIEhTViBmZWF0dXJlCgoKI0hlcmUgSSBwaWNrIDUgaW1hZ2VzICgzIGZyaWVkIGNoaWNrZW5zIGFuZCAyIGRvZ3MpIHRvIGRvIGEgaW1hZ2UgZXhsb3JhdGlvbiBkZW1vLgpgYGB7cn0Kc2V0d2QoIn4vR29vZ2xlIERyaXZlL0NvbHVtYmlhLzUyNDMgQURTL1Byb2plY3QgMy9Qcm9qZWN0M19wb29kbGVLRkNfdHJhaW4vaW1hZ2VzIikKCmxpYnJhcnkoIkVCSW1hZ2UiKQppMS5jIDwtIHJlYWRJbWFnZSgiY2hpY2tlbl8wMTE2LmpwZyIpICNjaGlja2VuIDEKaTIuYyA8LSByZWFkSW1hZ2UoImNoaWNrZW5fMDc2MS5qcGciKSAjY2hpY2tlbiAyCmkxLmQgPC0gcmVhZEltYWdlKCJkb2dfMDAyMS5qcGciKSAjZG9nIDEKaTIuZCA8LSByZWFkSW1hZ2UoImRvZ18wNjA4LmpwZyIpICNkb2cgMgppMSA8LSByZWFkSW1hZ2UoImNoaWNrZW5fMDEzMS5qcGciKSAjIGhhcmQtdG8tZGlzdGluZ3Vpc2ggY2hpY2tlbgoKZmlsZW5hbWU9bGlzdChpMS5jLGkyLmMsaTEuZCxpMi5kLGkxKSAjbGlzdCBhbGwgNSBpbWFnZXMKCm9wdGlvbnMoIkVCSW1hZ2UuZGlzcGxheSI9ICJyYXN0ZXIiKSAjZGlzcGxheSBpbiBSIHJhdGhlciB0aGFuIGluIGJyb3dzZXIKCnByaW50KGZpbGVuYW1lKSAjZGV0YWlsZWQgaW5mbyBvZiBhbGwgNSBpbWFnZXMgCgpmb3IgKGkgaW4gMTo1KXsKICBkaXNwbGF5KGZpbGVuYW1lW1tpXV0pICAgI2Rpc3BsYXkgaW1hZ2VzCiAgaGlzdChmaWxlbmFtZVtbaV1dKSAgICAgICNSR0IgaGlzdG9ncmFtcwp9CmBgYAoKCkNoYW5nZSB0byBHcmV5c2NhbGUsIGJsdWUgYW5kIHJlZCBjaGFubmVscwpgYGB7cn0KZmlsZS5idz1saXN0KCkKZmlsZS5ibD1saXN0KCkKZmlsZS5yZWQ9bGlzdCgpCgpmb3IgKGkgaW4gMTo1KXsKICBmaWxlLmJ3W1tpXV09Y2hhbm5lbChmaWxlbmFtZVtbaV1dLG1vZGU9ImdyZXkiKQogIGRpc3BsYXkoZmlsZS5id1tbaV1dKQp9Cgpmb3IgKGkgaW4gMTo1KSB7CiAgZmlsZS5ibFtbaV1dPWNoYW5uZWwoZmlsZW5hbWVbW2ldXSwgbW9kZT0nYXNibHVlJykKICBkaXNwbGF5KGNoYW5uZWwoZmlsZW5hbWVbW2ldXSwgbW9kZT0nYXNibHVlJykpCn0KCmZvciAoaSBpbiAxOjUpIHsKICBmaWxlLnJlZFtbaV1dPWNoYW5uZWwoZmlsZW5hbWVbW2ldXSwgbW9kZT0nYXNyZWQnKQogIGRpc3BsYXkoY2hhbm5lbChmaWxlbmFtZVtbaV1dLCBtb2RlPSdhc3JlZCcpKQp9CmBgYAoKCkV4dHJhY3QgdGhlIHRleHR1cmUgYnkgaGlnaCBjb250cmFzdCBvbiBibHVlIGNoYW5uZWwsIHdoaWNoIHJlYWxseSBzaG93cyBkaWZmZXJlbmNlIHRvIG1lIGJldHdlZW4gZnJpZWQgY2hpY2tlbiBhbmQgZG9ncy4KYGBge3J9CmZpbGUuY29udHJhc3Q9bGlzdCgpCmZvciAoaSBpbiAxOjUpewogIGZpbGUuY29udHJhc3Q9ZmlsZS5ibFtbaV1dKjUKICBkaXNwbGF5KGZpbGUuYmxbW2ldXSo1KQp9CmBgYAoKI0ZpbHRlcmluZzogaGlnaCBwYXNzCmBgYHtyfQpmaWx0ZXJfaGlnaCA8LSBtYXRyaXgoMSwgbmMgPSAzLCBuciA9IDMpCmZpbHRlcl9oaWdoWzIsIDJdIDwtIC04CmZpbGUuaGk9bGlzdCgpCmZvciAoaSBpbiAxOjUpewogIGZpbGUuaGkgPC0gZmlsdGVyMihmaWxlbmFtZVtbaV1dLCBmaWx0ZXJfaGlnaCkKICBkaXNwbGF5KGZpbGUuaGkpIyBoaWdoIHBhc3MKfQpgYGAKCiNBZGFwdGl2ZSB0aHJlc2hvbGRpbmcKYGBge3J9CmZvciAoaSBpbiAxOjUpewogIGZpbGUuYndbW2ldXT1jaGFubmVsKGZpbGVuYW1lW1tpXV0sbW9kZT0iZ3JleSIpCiAgaW1nX3NlZzEgPC0gdGhyZXNoKGZpbGUuYndbW2ldXSwgdz02MCwgaD02MCwgb2Zmc2V0PTAuMDYpCiAgZGlzcGxheShpbWdfc2VnMSwgYWxsPVRSVUUpCn0KYGBgCgoKIyBPdXRsaW5lIEFuYWx5c2lzCmBgYHtyfQojT3JpZW50ZWQgQ29udG91ciAjIyMgZGlkbid0IHNlZSBhbnkgdXNlIGhlcmUKaW1nX2xlYWY9bGlzdCgpCmltZ19sZWFmMT1saXN0KCkKb2M9bGlzdCgpCgpmb3IgKGkgaW4gMTo1KXsKICBpbWdfbGVhZltbaV1dIDwtIHJlc2l6ZShmaWxlbmFtZVtbaV1dLCAxMjgsIDEyOCkKICBpbWdfbGVhZltbaV1dIDwtIGNoYW5uZWwoaW1nX2xlYWZbW2ldXSwgbW9kZT0iZ3JheSIpCiAgaW1nX2xlYWYxW1tpXV0gPC0gdGhyZXNoKGltZ19sZWFmW1tpXV0sIHc9NTAsIGg9NTAsIG9mZnNldD0wLjA1KQogIGRpc3BsYXkoaW1nX2xlYWYxW1tpXV0pfQoKZm9yIChpIGluIDE6NSl7CiAgb2NbW2ldXSA8LSBvY29udG91cihid2xhYmVsKGltZ19sZWFmMVtbaV1dKSkKICBwbG90KG9jW1tpXV1bWzFdXSwgdHlwZT0nbCcpO3BvaW50cyhvY1tbaV1dW1sxXV0sIGNvbD0yKQp9CmBgYAoKYGBge3J9CiNMb2NhbCBDdXJ2YXR1cmUKbGM9bGlzdCgpCmk9bGlzdCgpCm5lZz1saXN0KCkKcG9zPWxpc3QoKQoKZm9yIChrIGluIDE6NSl7CiAgbGNbW2tdXSA8LSBsb2NhbEN1cnZhdHVyZSh4PW9jW1trXV1bWzFdXSwgaD0xMSkKICBpW1trXV0gPC0gbGNbW2tdXSRjdXJ2YXR1cmUgPj0gMAogIG5lZ1tba11dIDwtIGFycmF5KDAsIGRpbShpbWdfbGVhZjFbW2tdXSkpCiAgcG9zW1trXV0gPC0gbmVnW1trXV0KICBwb3NbW2tdXVtsY1tba11dJGNvbnRvdXJbaVtba11dLF0rMV0gIDwtIGxjW1trXV0kY3VydmF0dXJlW2lbW2tdXV0KICBuZWdbW2tdXVtsY1tba11dJGNvbnRvdXJbIWlbW2tdXSxdKzFdIDwtIC1sY1tba11dJGN1cnZhdHVyZVshaVtba11dXQogIGRpc3BsYXkoMTAqKHJnYkltYWdlKHBvc1tba11dLCAsIG5lZ1tba11dKSksIHRpdGxlID0gIkltYWdlIGN1cnZhdHVyZSIpCn0KYGBgCgpDb2xvciBGZWF0dXJlcyBmcm9tIFJHQgoKQnkgZGlzY3JldGl6aW5nIHRoZSBSR0IgdmFsdWVzLCB3ZSBjYW4gZ2V0IGEgc2V0IG9mIGNvbG9yIGZlYXR1cmVzLiBXZSBzdWJkaXZpZGUgdGhlIHBpeGVsIHZhbHVlcyBpbiBlYWNoIGNvbG9yIGNoYW5uZWwgaW50byBtdWx0aXBsZSBiYW5kcyBvZiBlcXVhbCB3aWR0aC4gVGhlbiB0aGUgY291bnRzIG9mIHBpeGVscyBpbiBjb3JyZXBvbmRpbmcgYmlucyBjb25zaXN0IG9mIGEgc2V0IG9mIGNvbG9yIGZlYXR1cmVzIHRoYXQgY2hhcmFjdGVyaXplcyB0aGUgY29sb3IgZGlzdHJpYnV0aW9uIG9mIHRoZSBpbWFnZS4KYGBge3J9Cm1hdD1saXN0KCkKZnJlcV9yZ2I9bGlzdCgpCnJnYl9mZWF0dXJlPWxpc3QoKQoKblIgPC0gMTAKbkcgPC0gOApuQiA8LSAxMCAjIENhdXRpb246IHRoZSBiaW5zIHNob3VsZCBiZSBjb25zaXN0ZW50IGFjcm9zcyBhbGwgaW1hZ2VzIQpyQmluIDwtIHNlcSgwLCAxLCBsZW5ndGgub3V0PW5SKQpnQmluIDwtIHNlcSgwLCAxLCBsZW5ndGgub3V0PW5HKQpiQmluIDwtIHNlcSgwLCAxLCBsZW5ndGgub3V0PW5CKQoKZm9yIChpIGluIDE6NSl7CiAgbWF0W1tpXV0gPC0gaW1hZ2VEYXRhKGZpbGVuYW1lW1tpXV0pCiAgZnJlcV9yZ2JbW2ldXSA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKGZhY3RvcihmaW5kSW50ZXJ2YWwobWF0W1tpXV1bLCwxXSwgckJpbiksIGxldmVscz0xOm5SKSwgZmFjdG9yKGZpbmRJbnRlcnZhbChtYXRbW2ldXVssLDJdLCBnQmluKSwgbGV2ZWxzPTE6bkcpLCBmYWN0b3IoZmluZEludGVydmFsKG1hdFtbaV1dWywsM10sIGJCaW4pLCBsZXZlbHM9MTpuQikpKQogIHJnYl9mZWF0dXJlW1tpXV0gPC0gYXMubnVtZXJpYyhmcmVxX3JnYltbaV1dJEZyZXEpLyhuY29sKG1hdFtbaV1dKSpucm93KG1hdFtbaV1dKSkgIyBub3JtYWxpemF0aW9uCn0KCnN0cihyZ2JfZmVhdHVyZSkgI2VhY2ggaW1hZ2UgaGFzIDgwMCBmZWF0dXJlcwojVGhlIG51bWJlciBvZiBiaW5zIGZvciBlYWNoIGNvbG9yIGNoYW5uZWwgKG5SLG5HLG5CKSBpcyBhIHR1bmluZyBwYXJhbWV0ZXIgZm9yIGNvbnN0cnVjdGluZyBjb2xvciBmZWF0dXJlcy4gVGhlIHRvdGFsIG51bWJlciBvZiBmZWF0dXJlcyBpcyBuUipuRypuQi4KYGBg